package za.co.EYEWTKAH.spring.jms.embedded;

import java.util.ArrayList;

import javax.jms.ConnectionFactory;

import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.core.config.Configuration;
import org.hornetq.core.config.impl.ConfigurationImpl;
import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
import org.hornetq.jms.server.config.ConnectionFactoryConfiguration;
import org.hornetq.jms.server.config.JMSConfiguration;
import org.hornetq.jms.server.config.JMSQueueConfiguration;
import org.hornetq.jms.server.config.TopicConfiguration;
import org.hornetq.jms.server.config.impl.ConnectionFactoryConfigurationImpl;
import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
import org.hornetq.jms.server.embedded.EmbeddedJMS;

public class HornetQConnectionFactoryBuilder extends
		EmbeddedConnectionFactoryBuilder {

	private EmbeddedJMS jmsServer;

	public HornetQConnectionFactoryBuilder(
			EmbeddedConnectionFactoryConfiguration configuration) {
		super(configuration);

	}

	@Override
	public EmbeddedConnectionFactory getConnectionFactory()
			throws EmbeddedConnectionFactoryException {

		// Step 1. Create HornetQ core configuration, and set the properties
		// accordingly
		Configuration configuration = new ConfigurationImpl();
		configuration.setPersistenceEnabled(false);
		configuration.setJournalDirectory("target/data/journal");
		configuration.setSecurityEnabled(false);
		configuration.getAcceptorConfigurations()
				.add(new TransportConfiguration(NettyAcceptorFactory.class
						.getName()));

		TransportConfiguration connectorConfig = new TransportConfiguration(
				NettyConnectorFactory.class.getName());

		configuration.getConnectorConfigurations().put("connector",
				connectorConfig);

		// Step 2. Create the JMS configuration
		JMSConfiguration jmsConfig = new JMSConfigurationImpl();

		// Step 3. Configure the JMS ConnectionFactory
		ArrayList<String> connectorNames = new ArrayList<String>();
		connectorNames.add("connector");
		ConnectionFactoryConfiguration cfConfig = new ConnectionFactoryConfigurationImpl(
				"cf", false, connectorNames, "/cf");
		jmsConfig.getConnectionFactoryConfigurations().add(cfConfig);

		// Step 4. Configure the JMS Queue
		for (String queueName : super.configuration.getQueueNames()) {
			JMSQueueConfiguration queueConfig = new JMSQueueConfigurationImpl(
					queueName, null, false, "/queue/" + queueName);
			jmsConfig.getQueueConfigurations().add(queueConfig);
		}

		for (String topicName : super.configuration.getTopicNames()) {
			TopicConfiguration a = new TopicConfigurationImpl(topicName,
					"/topic/" + topicName);
			jmsConfig.getTopicConfigurations().add(a);
		}

		// Step 5. Start the JMS Server using the HornetQ core server and the
		// JMS configuration
		jmsServer = new EmbeddedJMS();
		jmsServer.setConfiguration(configuration);
		jmsServer.setJmsConfiguration(jmsConfig);
		try {
			jmsServer.start();
		} catch (Exception e) {
			throw new EmbeddedConnectionFactoryException(
					"Failed to start HornetQ Jms server", e,
					EmbeddedConnectionFactoryType.HORNETQ);
		}

		// Step 6. Lookup JMS resources defined in the configuration
		ConnectionFactory cf = (ConnectionFactory) jmsServer.lookup("/cf");
		return proxy(this, cf);

	}

	@Override
	public void shutDown() throws EmbeddedConnectionFactoryException {
		try {
			jmsServer.stop();
		} catch (Exception e) {
			throw new EmbeddedConnectionFactoryException(
					"Failed to stop HornetQ Jms server", e,
					EmbeddedConnectionFactoryType.HORNETQ);
		}

	}

}
